package junk;
import processing.core.PApplet;



public class BooleanGroup extends Protein{
	public static int numInGroup = 0;
	public static boolean booleanGroupCreated = false;
	public static Protein booleanGroup;
	public static int proteinGroupsSizeColumn;
	
	public Protein protein1;
	public Protein protein2;
	public boolean not1, not2;
	public int sign1, sign2;
	public String operation;
	public int itemsInGroup;
	
	public BooleanGroup ( boolean n1, int s1, Protein p1, String op, boolean n2, int s2, Protein p2, PApplet p)
	{
		super("Boolean", p);
		protein1 = p1;
		protein2 = p2;
		not1 = n1;
		not2 = n2;
		sign1 = s1;
		sign2 = s2;
		operation = op;
		if(p1 instanceof BooleanGroup)
		{
			BooleanGroup b1 = (BooleanGroup) p1;
			itemsInGroup = b1.itemsInGroup;
		}
		else itemsInGroup = 1;
		if(p2 instanceof BooleanGroup)
		{
			BooleanGroup b2 = (BooleanGroup) p2;
			itemsInGroup = itemsInGroup + b2.itemsInGroup;
		}
		else itemsInGroup = itemsInGroup + 1;
		
		String sgn1, sgn2;
		if(sign1>0) sgn1 = "+";
		else if( sign1<0) sgn1 = "-";
		else sgn1 = "";
		if(sign2>0) sgn2 = "+";
		else if( sign2<0) sgn2 = "-";
		else sgn2 = "";
		if(!n1 && !n2) name = sgn1 + p1.name +"\n" + op + " " + sgn2 + p2.name;
		else if(n1 && !n2) name = "!"+sgn1 + p1.name +"\n" + op + " " + sgn2 + p2.name;
		else if(!n1 && n2) name = sgn1 + p1.name +"\n" + op + " !" + sgn2 + p2.name;
		else if(n1 && n2) name = "!" + sgn1 + p1.name +"\n" + op + " !" + sgn2 + p2.name;
		
		if(!booleanGroupCreated) 
		{
			Protein[] proteinListCopy = new Protein[proteinList.length + 1];
			for(int i = 0; i< proteinList.length; i++)
				proteinListCopy[i] = proteinList[i];
			booleanGroup = new Protein("Group", "Boolean", "Groups", p);
			proteinListCopy[proteinList.length] = booleanGroup;
			proteinList= proteinListCopy;
			
			String[] proteinGroupsCopy = new String[Main1.proteinGroups.length + 1];
			for(int i = 0; i< Main1.proteinGroups.length; i++)
				proteinGroupsCopy[i] = Main1.proteinGroups[i];
			proteinGroupsCopy[Main1.proteinGroups.length] = "Boolean";
			Main1.proteinGroups= proteinGroupsCopy;
			booleanGroupCreated = true;
			
			int[] proteinGroupsSizeCopy = new int[Main1.proteinGroupsSize.length + 1];
			for(int i = 0; i< Main1.proteinGroupsSize.length; i++)
				proteinGroupsSizeCopy[i] = Main1.proteinGroupsSize[i];
			proteinGroupsSizeCopy[Main1.proteinGroupsSize.length] = 0;
			Main1.proteinGroupsSize= proteinGroupsSizeCopy;
			proteinGroupsSizeColumn = proteinGroupsSizeCopy.length - 1;
			Protein.allProteins.children.add(booleanGroup);
		
			booleanGroupCreated = true;
		}
		
		booleanGroup.children.add(this);
		this.parentProtein = booleanGroup;
		Protein[] proteinListCopy = new Protein[proteinList.length + 1];
		for(int i = 0; i< proteinList.length; i++)
			proteinListCopy[i] = proteinList[i];
		proteinListCopy[proteinList.length] = this;
		proteinList= proteinListCopy;
		Main1.proteinGroupsSize[proteinGroupsSizeColumn] = Main1.proteinGroupsSize[proteinGroupsSizeColumn] + 1;
		
		for( int i = 0; i< proteinList.length; i++)
			proteinList[i].setCoordinates( proteinList.length);		
		drawProteins();
		
	}
	public void drawMe( boolean findMouse ) {
		parent.rectMode(Main1.CENTER);
		drawLines();
		String display;
		display = name;
		width = parent.width*.05f;
		height = .02f*itemsInGroup*parent.height;
		
		if (isSelected) parent.fill(parent.color(255,102,31));
		else parent.fill(parent.color(255,102,31,100));
		parent.stroke(parent.color(147,61,21));
		parent.strokeWeight(5);
		((Main1) parent).roundRect(x1-(width*.5f),y1-(height*.5f),width,height);
		parent.textFont(Main1.font10);
		if (isSelected) parent.fill(parent.color(0));
		else parent.fill(212,240,123);
		parent.textAlign(Main1.CENTER);
		parent.text(display, x1, y1-7*(itemsInGroup-1));
		
		parent.strokeWeight(1);
		parent.textAlign(Main1.LEFT);
	}
	public void drawLines()
	{
		Gene[] geneList = Main1.firstAnnotation.genes;
		int radius  = (int)(Main1.innerRadius*.99);
		for (int i = 0; i< geneList.length; i++)
		{
				if (drawLine(i))
				{						
					Gene gene = Main1.firstAnnotation.genes[i];
					
					int idx  = gene.numAnnotations - 1;
		    		float c1X = gene.groupHeigherarchy[0].centerX;
		    		float c1Y = -gene.groupHeigherarchy[0].centerY;
		    		float c2X = 0;
		    		float c2Y = 0;
		    		if(idx >1)
		    		{
		    			c2X = gene.groupHeigherarchy[1].centerX;
		    			c2Y = -gene.groupHeigherarchy[1].centerY;
		    		}
		    		float geneX, geneY;
		    		if(gene.active)
		    		{
		    			geneX = (float) gene.x*radius;
		    			geneY = (float)-gene.y*radius;
		    		}
		    		else
		    		{
		    			geneX = gene.activeAnnotation.midX;
		    			geneY = gene.activeAnnotation.midY;
		    		}
		    		if(!isSelected) parent.stroke(128,25);
		    		else parent.stroke(proteinColor(numInGroup, myOpacity));
		    		parent.noFill();    
		    		if(showMe && showBinding)
		    		{
		    			if(idx > 1) parent.bezier(geneX, geneY,c1X, c1Y, c2X, c2Y, x1, y1);
		    			else parent.bezier(geneX, geneY, c1X, c1Y, 0, 0, x1, y1);
		    		}
		    	}
			}
			
		}
	
	public boolean drawLine(int i)
	{
		Gene[] geneList = Main1.firstAnnotation.genes;
		double pValueCutoff = Main1.pValueCutoff;
		double expressionCutoff = Main1.expressionCutoff;
		
		int j = protein1.columnInData;
		int k = protein2.columnInData;
		
		boolean drawLine1 = false;
		boolean drawLine2 = false;
		boolean drawLine;	
		if (protein1 instanceof BooleanGroup)
		{
			
			BooleanGroup booleanProtein = (BooleanGroup) protein1;
			drawLine1 = booleanProtein.drawLine(i);
		}
		else 
		{
			for(int z = 0; z< ReadGenes.datasets.length; z++)
			{
				if(protein1.set.equals(ReadGenes.datasets[z]))
				{
					if(protein1.type.equals("Raw"))
					{
						drawLine1 = (Math.pow(geneList[i].expressionConditions.get(z)[j],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(z)[j]) == sign1);
					}
					else
					{
						drawLine1 = geneList[i].expressionConditions.get(z)[j] < pValueCutoff;
					}
				}
			}
			
		}
			/*
			if(protein1.annotation.equals("Control"))
					drawLine1 = (Math.pow(geneList[i].expressionConditions.get(0)[j],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(0)[j]) == sign1);
			else if(protein1.annotation.equals("HP"))
				drawLine1 = (Math.pow(geneList[i].expressionConditions.get(1)[j],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(1)[j]) == sign1);
			else if(protein1.annotation.equals("MD"))
				drawLine1 = (Math.pow(geneList[i].expressionConditions.get(2)[j],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(2)[j]) == sign1);
			else
				drawLine1 = (Math.pow(geneList[i].expressionConditions.get(3)[j],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(3)[j]) == sign1);
			*/
		
		if (protein2 instanceof BooleanGroup)
		{
			
			BooleanGroup booleanProtein = (BooleanGroup) protein2;
			drawLine2 = booleanProtein.drawLine(i);
		}
		else 
		{
			for(int z = 0; z< ReadGenes.datasets.length; z++)
			{
				if(protein2.set.equals(ReadGenes.datasets[z]))
				{
					if(protein2.set.equals(ReadGenes.datasets[z]))
					{
						drawLine2 = (Math.pow(geneList[i].expressionConditions.get(z)[k],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(z)[k]) == sign2);
					}
					else
					{
						drawLine2 = geneList[i].expressionConditions.get(z)[k] < pValueCutoff;
					}
				}
			}
			
		
		
			/*
			if(protein2.annotation.equals("Control"))
				drawLine2 = (Math.pow(geneList[i].expressionConditions.get(0)[k],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(0)[k]) == sign2);
			else if(protein2.annotation.equals("HP"))
				drawLine2 = (Math.pow(geneList[i].expressionConditions.get(1)[k],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(1)[k]) == sign2);
			else if(protein2.annotation.equals("MD"))
				drawLine2 = (Math.pow(geneList[i].expressionConditions.get(2)[k],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(2)[k]) == sign2);
			else
				drawLine2 = (Math.pow(geneList[i].expressionConditions.get(3)[k],2) > expressionCutoff) && (Math.signum(geneList[i].expressionConditions.get(3)[k]) == sign2);
				*/
		}
		if(not1) drawLine1 = !drawLine1;
		if(not2) drawLine2 = !drawLine2;
		if(operation.equals("AND")) drawLine = drawLine1 && drawLine2;
		else drawLine = drawLine1 || drawLine2;
		return drawLine;
	}
	public double percentExpression( int row)
	{
		double percent;
		if(protein1 instanceof BooleanGroup)
		{
			BooleanGroup b = (BooleanGroup) protein1;
			percent = b.percentExpression(row);
		}
		else 
		{
			int dataset = -1;		
			for( int z = 0; z< ReadGenes.datasets.length; z++)
			{
				if(protein1.annotation.equals(ReadGenes.datasets[z]))
					dataset = z;
				else if(protein1.set.equals(ReadGenes.datasets[z]))
					dataset = z;
			}	
			percent = Main1.firstAnnotation.genes[row].percentExpressionConditions.get(dataset)[protein1.columnInData];
		}
	
		
		if(protein2 instanceof BooleanGroup)
		{
			BooleanGroup b = (BooleanGroup) protein2;
			percent = percent + b.percentExpression(row);
		}
		else
		{
			int dataset = -1;		
			for( int z = 0; z< ReadGenes.datasets.length; z++)
			{
				if(protein2.annotation.equals(ReadGenes.datasets[z]))
					dataset = z;
				else if(protein2.set.equals(ReadGenes.datasets[z]))
					dataset = z;
			}	
			percent = percent + Main1.firstAnnotation.genes[row].percentExpressionConditions.get(dataset)[protein2.columnInData];
		}
		return percent;
	}

}
